/*
 * process.cpp
 *
 *  Created on: Dec 8, 2021
 *      Author: t1019
 */
#include "matrixkeyboard.h"
#include "ledset.h"
#include "cmdinterpreter.h"
#include "main.h"
#ifdef __cplusplus
extern "C"{
#endif

using namespace bt_matrixkeyboard;
using namespace bt_led;
using namespace bt_cmdinterpreter;

void _update_led();
void _cmd_cb_4(char* code);
void _cmd_cb_n4(char* code);
void _cmd_cb_nn(char* code);
void _cmd_cb_n(char* code);
void _cmd_cb_sf(char* code);
void _cmd_cb_f(char* code);
void _cmd_cb_s(char* code);
void _cmd_cb_root(char* code);

char martixvalue[3*3] =
{	// out1 out2 out3
		'0','1','2',	//in1
		'a','b','c',	//in2
		'4','s','q'		//in3
};

const s_MatrixKeyboardLine outlines[3] =
{
		{.gpio = TEST1_GPIO_Port,.pin = TEST1_Pin},
		{.gpio = TEST2_GPIO_Port,.pin = TEST2_Pin},
		{.gpio = TEST3_GPIO_Port,.pin = TEST3_Pin}
};

const s_MatrixKeyboardLine inlines[3] =
{
		{.gpio = DET1_GPIO_Port,.pin = DET1_Pin},
		{.gpio = DET2_GPIO_Port,.pin = DET2_Pin},
		{.gpio = DET3_GPIO_Port,.pin = DET3_Pin}
};

const s_SingleLed led[5] =
{
		{.gpio = LED_M_GPIO_Port,.pin = LED_M_Pin},
		{.gpio = LED_N_GPIO_Port,.pin = LED_N_Pin},
		{.gpio = LED_S_GPIO_Port,.pin = LED_S_Pin},
		{.gpio = LED_F_GPIO_Port,.pin = LED_F_Pin},
		{.gpio = LED_Q_GPIO_Port,.pin = LED_Q_Pin}
};

#define CMD_GROUP_N 	0x81
#define CMD_GROUP_F 	0x82
const s_CmdGroup cmd_group[] =
{
		{.event = CMD_GROUP_N,.group = "012"},
		{.event = CMD_GROUP_F,.group = "abc"}
};


s_CmdNode cmd_4 =
{
		.event = '4',
		.node = 0,
		.next = 0,
		.func = _cmd_cb_4,
		.parent = 0
};

s_CmdNode cmd_n4 =
{
		.event = '4',
		.node = 0,
		.next = 0,
		.func = _cmd_cb_n4,
		.parent = 0
};

s_CmdNode cmd_nn =
{
		.event = CMD_GROUP_N,
		.node = 0,
		.next = &cmd_n4,
		.func = _cmd_cb_nn,
		.parent = 0
};

s_CmdNode cmd_n =
{
		.event = CMD_GROUP_N,
		.node = &cmd_nn,
		.next = &cmd_4,
		.func = _cmd_cb_n,
		.parent = 0
};

s_CmdNode cmd_sf =
{
		.event = CMD_GROUP_F,
		.node = 0,
		.next = 0,
		.func = _cmd_cb_sf,
		.parent = 0
};

s_CmdNode cmd_s =
{
		.event = 's',
		.node = &cmd_sf,
		.next = &cmd_n,
		.func = _cmd_cb_s,
		.parent = 0
};

s_CmdNode cmd_f =
{
		.event = CMD_GROUP_F,
		.node = 0,
		.next = &cmd_s,
		.func = _cmd_cb_f,
		.parent = 0
};

s_CmdNode cmd_root =
{
		.event = '\0',
		.node = &cmd_f,
		.next = 0,
		.func = _cmd_cb_root,
		.parent = 0
};

LedSet ledm(&led[0]),ledn(&led[1]),leds(&led[2]),ledf(&led[3]),ledq(&led[4]);
uint8_t mode = 0x3f;
uint8_t save[3] = {0x36,0x39,0x3f};
uint8_t save_index = 0;
void process(void)
{
	CmdInterpreter cmd(&cmd_root);
	cmd.setGroups(cmd_group);
	cmd.setQuit('q');
	MatrixKeyboard keyboard(3,3);
	keyboard.setLines(outlines,inlines);
	keyboard.setValue(martixvalue);
	_update_led();
	while(1)
	{
		keyboard.handler(5);
		cmd.handler(keyboard.getEvent());
		LedSet::handler(5);
		HAL_Delay(5);
	}
}

void _cmd_cb_4(char* code)
{
	if(mode == 0x3f)
	{
		mode = save[save_index];
		ledm.set(SLED_FAST,1000,SLED_ON);
	}
	else
	{
		mode = 0x3f;
		ledm.set(SLED_FAST,1000,SLED_SLOW);
	}
	ledn.set(SLED_OFF);
	leds.set(SLED_OFF);
	ledf.set(SLED_OFF);
	ledq.set(SLED_OFF);
	//TODO 保存
	//TODO 发送
}
void _cmd_cb_n4(char* code)
{
	uint8_t idx = code[0] - '0';
	mode |= (1<<(idx*2));
	mode |= (1<<(idx*2+1));
	_update_led();
	if(mode == 0x3f)
		ledm.set(SLED_FAST,1000,SLED_SLOW);
	else
		ledm.set(SLED_FAST,1000,SLED_ON);
	//TODO 保存
	//TODO 发送
}
void _cmd_cb_nn(char* code)
{
	uint8_t idx1 = code[0] - '0';
	uint8_t idx2 = code[1] - '0';
	mode &= ~((0x03)<<(idx1*2));
	mode |= (idx2<<(idx1*2));
	_update_led();
	ledn.set(SLED_FAST,1000,SLED_OFF);
	//TODO 保存
	//TODO 发送
}
void _cmd_cb_n(char* code)
{
	ledn.set(SLED_ON);
	ledm.set(SLED_ON);
	leds.set(SLED_OFF);
	ledf.set(SLED_OFF);
	ledq.set(SLED_ON);
}
void _cmd_cb_sf(char* code)
{
	uint8_t idx2 = code[1] - '0';
	save[idx2] = mode;
	_update_led();
	ledf.set(SLED_FAST,1000,SLED_OFF);
	leds.set(SLED_FAST,1000,SLED_OFF);
	//TODO 保存
}
void _cmd_cb_f(char* code)
{
	uint8_t idx1 = code[0] - 'a';
	save_index = idx1;
	mode = save[idx1];
	_update_led();
	ledf.set(SLED_FAST,1000,SLED_OFF);
	//TODO 保存
	//TODO 发送
}
void _cmd_cb_s(char* code)
{
	ledn.set(SLED_OFF);
	ledm.set(SLED_OFF);
	leds.set(SLED_OFF);
	ledf.set(SLED_ON);
	ledq.set(SLED_ON);
}
void _cmd_cb_root(char* code)
{
	ledn.set(SLED_OFF);
	_update_led();
}

void _update_led()
{
	ledn.set(SLED_OFF);
	if(mode == 0x3f)
		ledm.set(SLED_SLOW);
	else
		ledm.set(SLED_ON);
	leds.set(SLED_OFF);
	ledf.set(SLED_OFF);
	ledq.set(SLED_OFF);
}

#ifdef __cplusplus
}
#endif
